//
// File: sparse.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 27-Mar-2025 11:51:36
//

// Include Files
#include "sparse.h"
#include "CXSparseAPI.h"
#include "introsort.h"
#include "rt_nonfinite.h"
#include "speye.h"
#include "coder_array.h"
#include "CXSparseSupport/cs.h"
#include "CXSparseSupport/makeCXSparseMatrix.h"
#include "CXSparseSupport/solve_from_lu.h"
#include <cstddef>
#include <cstring>

// Function Definitions
//
// Arguments    : const sparse *a
//                const sparse *b
//                int sn
//                int sm
//                sparse *s
// Return Type  : void
//
namespace coder {
void sparse::allocEqsizeBinop(const sparse *a, const sparse *b, int sn, int sm,
                              sparse *s)
{
  int nza;
  int nzb;
  nza = a->colidx[a->colidx.size(0) - 1] - 1;
  nzb = b->colidx[b->colidx.size(0) - 1] - 1;
  if ((a->m != b->m) || (a->n != b->n)) {
    if (a->n == 1) {
      nza = (a->colidx[a->colidx.size(0) - 1] - 1) * b->n;
    } else if (a->m == 1) {
      nza = (a->colidx[a->colidx.size(0) - 1] - 1) * b->m;
    }
    if (b->n == 1) {
      nzb = (b->colidx[b->colidx.size(0) - 1] - 1) * a->n;
    } else if (a->m == 1) {
      nzb = b->colidx[b->colidx.size(0) - 1] - 1;
    }
  }
  nza += nzb;
  nzb = sn * sm;
  if (nza <= nzb) {
    nzb = nza;
  }
  if (nzb < 1) {
    nzb = 1;
  }
  s->m = sm;
  s->n = sn;
  s->maxnz = nzb;
  s->d.set_size(nzb);
  s->rowidx.set_size(nzb);
  s->colidx.set_size(sn + 1);
}

//
// Arguments    : void
// Return Type  : void
//
void sparse::b_fillIn()
{
  int i;
  int idx;
  idx = 1;
  i = colidx.size(0);
  for (int c{0}; c <= i - 2; c++) {
    int ridx;
    ridx = colidx[c];
    colidx[c] = idx;
    while (ridx < colidx[c + 1]) {
      double val;
      int currRowIdx;
      currRowIdx = rowidx[ridx - 1];
      val = d[ridx - 1];
      ridx++;
      if (val != 0.0) {
        d[idx - 1] = val;
        rowidx[idx - 1] = currRowIdx;
        idx++;
      }
    }
  }
  colidx[colidx.size(0) - 1] = idx;
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
//                boolean_T expandB
// Return Type  : void
//
void sparse::b_sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                          sparse *s, boolean_T expandB)
{
  int b_n;
  int bc;
  int bcInc;
  int didx;
  didx = 0;
  s->colidx[0] = 1;
  b_n = s->n;
  bc = 0;
  bcInc = !expandB;
  for (int c{0}; c < b_n; c++) {
    int av;
    int i;
    av = (rowA->colidx[c] != rowA->colidx[c + 1]);
    i = b->colidx[bc + 1];
    if (b->colidx[bc] == i) {
      if (av != 0) {
        i = s->m;
        for (int r{0}; r < i; r++) {
          av = didx + r;
          s->d[av] = 1.0;
          s->rowidx[av] = r + 1;
        }
        didx += i;
      }
      s->colidx[c + 1] = didx + 1;
      bc += bcInc;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      int offset;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[bc] - 1];
      lastNonZeroRow_tmp = b->rowidx[i - 2];
      if (av != 0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          i = didx + r;
          s->d[i] = 1.0;
          s->rowidx[i] = r + 1;
        }
        didx = (didx + firstNonZeroRow_tmp) - 1;
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        i = b->colidx[bc] + offset;
        if (b->rowidx[i] == r) {
          double val;
          val = static_cast<double>(av) - b->d[i];
          if (val != 0.0) {
            s->d[didx] = val;
            s->rowidx[didx] = r;
            didx++;
          }
          offset++;
        } else if (av != 0) {
          s->d[didx] = 1.0;
          s->rowidx[didx] = r;
          didx++;
        }
      }
      if (av != 0) {
        i = lastNonZeroRow_tmp + 1;
        av = s->m;
        for (int r{i}; r <= av; r++) {
          firstNonZeroRow_tmp = ((didx + r) - lastNonZeroRow_tmp) - 1;
          s->rowidx[firstNonZeroRow_tmp] = r;
          s->d[firstNonZeroRow_tmp] = 1.0;
        }
        didx = (didx + av) - lastNonZeroRow_tmp;
      }
      s->colidx[c + 1] = didx + 1;
      bc += bcInc;
    }
  }
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::c_sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                          sparse *s)
{
  int b_n;
  int didx;
  didx = 1;
  s->colidx[0] = 1;
  b_n = s->n;
  for (int c{0}; c < b_n; c++) {
    double av;
    if (rowA->colidx[c] == rowA->colidx[c + 1]) {
      av = 0.0;
    } else {
      av = rowA->d[rowA->colidx[c] - 1];
    }
    if (b->colidx[0] == b->colidx[1]) {
      if (av != 0.0) {
        int firstNonZeroRow_tmp;
        firstNonZeroRow_tmp = s->m;
        for (int r{0}; r < firstNonZeroRow_tmp; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      int offset;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[0] - 1];
      lastNonZeroRow_tmp = b->rowidx[b->colidx[1] - 2];
      if (av != 0.0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        if (b->rowidx[b->colidx[0] + offset] == r) {
          if (av + 1.0 != 0.0) {
            s->d[didx - 1] = av + 1.0;
            s->rowidx[didx - 1] = r;
            didx++;
          }
          offset++;
        } else if (av != 0.0) {
          s->d[didx - 1] = av;
          s->rowidx[didx - 1] = r;
          didx++;
        }
      }
      if (av != 0.0) {
        firstNonZeroRow_tmp = lastNonZeroRow_tmp + 1;
        lastNonZeroRow_tmp = s->m;
        for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
    }
  }
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::d_sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                          sparse *s)
{
  int b_n;
  int bc;
  int didx;
  didx = 1;
  s->colidx[0] = 1;
  b_n = s->n;
  bc = 0;
  for (int c{0}; c < b_n; c++) {
    double av;
    int offset;
    if (rowA->colidx[c] == rowA->colidx[c + 1]) {
      av = 0.0;
    } else {
      av = rowA->d[rowA->colidx[c] - 1];
    }
    offset = b->colidx[bc + 1];
    if (b->colidx[bc] == offset) {
      if (av != 0.0) {
        offset = s->m;
        for (int r{0}; r < offset; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
      bc++;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[bc] - 1];
      lastNonZeroRow_tmp = b->rowidx[offset - 2];
      if (av != 0.0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        if (b->rowidx[b->colidx[bc] + offset] == r) {
          if (av + 1.0 != 0.0) {
            s->d[didx - 1] = av + 1.0;
            s->rowidx[didx - 1] = r;
            didx++;
          }
          offset++;
        } else if (av != 0.0) {
          s->d[didx - 1] = av;
          s->rowidx[didx - 1] = r;
          didx++;
        }
      }
      if (av != 0.0) {
        offset = lastNonZeroRow_tmp + 1;
        lastNonZeroRow_tmp = s->m;
        for (int r{offset}; r <= lastNonZeroRow_tmp; r++) {
          if (av != 0.0) {
            s->d[didx - 1] = av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
      bc++;
    }
  }
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::e_sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                          sparse *s)
{
  int b_n;
  int didx;
  didx = 1;
  s->colidx[0] = 1;
  b_n = s->n;
  for (int c{0}; c < b_n; c++) {
    double av;
    if (rowA->colidx[c] == rowA->colidx[c + 1]) {
      av = 0.0;
    } else {
      av = rowA->d[rowA->colidx[c] - 1];
    }
    if (b->colidx[0] == b->colidx[1]) {
      if (0.0 - av != 0.0) {
        int firstNonZeroRow_tmp;
        firstNonZeroRow_tmp = s->m;
        for (int r{0}; r < firstNonZeroRow_tmp; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      int offset;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[0] - 1];
      lastNonZeroRow_tmp = b->rowidx[b->colidx[1] - 2];
      if (0.0 - av != 0.0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        if (b->rowidx[b->colidx[0] + offset] == r) {
          if (1.0 - av != 0.0) {
            s->d[didx - 1] = 1.0 - av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
          offset++;
        } else if (0.0 - av != 0.0) {
          s->d[didx - 1] = 0.0 - av;
          s->rowidx[didx - 1] = r;
          didx++;
        }
      }
      if (0.0 - av != 0.0) {
        firstNonZeroRow_tmp = lastNonZeroRow_tmp + 1;
        lastNonZeroRow_tmp = s->m;
        for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
    }
  }
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::f_sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                          sparse *s)
{
  int b_n;
  int bc;
  int didx;
  didx = 1;
  s->colidx[0] = 1;
  b_n = s->n;
  bc = 0;
  for (int c{0}; c < b_n; c++) {
    double av;
    int offset;
    if (rowA->colidx[c] == rowA->colidx[c + 1]) {
      av = 0.0;
    } else {
      av = rowA->d[rowA->colidx[c] - 1];
    }
    offset = b->colidx[bc + 1];
    if (b->colidx[bc] == offset) {
      if (0.0 - av != 0.0) {
        offset = s->m;
        for (int r{0}; r < offset; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
      bc++;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[bc] - 1];
      lastNonZeroRow_tmp = b->rowidx[offset - 2];
      if (0.0 - av != 0.0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r + 1;
            didx++;
          }
        }
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        if (b->rowidx[b->colidx[bc] + offset] == r) {
          if (1.0 - av != 0.0) {
            s->d[didx - 1] = 1.0 - av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
          offset++;
        } else if (0.0 - av != 0.0) {
          s->d[didx - 1] = 0.0 - av;
          s->rowidx[didx - 1] = r;
          didx++;
        }
      }
      if (0.0 - av != 0.0) {
        offset = lastNonZeroRow_tmp + 1;
        lastNonZeroRow_tmp = s->m;
        for (int r{offset}; r <= lastNonZeroRow_tmp; r++) {
          if (0.0 - av != 0.0) {
            s->d[didx - 1] = 0.0 - av;
            s->rowidx[didx - 1] = r;
            didx++;
          }
        }
      }
      s->colidx[c + 1] = didx;
      bc++;
    }
  }
}

//
// Arguments    : const sparse *rowA
//                const sparse *b
//                sparse *s
//                boolean_T expandB
// Return Type  : void
//
void sparse::sparseSparseRowExpandBinOp(const sparse *rowA, const sparse *b,
                                        sparse *s, boolean_T expandB)
{
  int b_n;
  int bc;
  int bcInc;
  int didx;
  didx = 0;
  s->colidx[0] = 1;
  b_n = s->n;
  bc = 0;
  bcInc = !expandB;
  for (int c{0}; c < b_n; c++) {
    int av;
    int i;
    av = (rowA->colidx[c] != rowA->colidx[c + 1]);
    i = b->colidx[bc + 1];
    if (b->colidx[bc] == i) {
      if (av != 0) {
        i = s->m;
        for (int r{0}; r < i; r++) {
          av = didx + r;
          s->d[av] = 1.0;
          s->rowidx[av] = r + 1;
        }
        didx += i;
      }
      s->colidx[c + 1] = didx + 1;
      bc += bcInc;
    } else {
      int firstNonZeroRow_tmp;
      int lastNonZeroRow_tmp;
      int offset;
      firstNonZeroRow_tmp = b->rowidx[b->colidx[bc] - 1];
      lastNonZeroRow_tmp = b->rowidx[i - 2];
      if (av != 0) {
        for (int r{0}; r <= firstNonZeroRow_tmp - 2; r++) {
          i = didx + r;
          s->d[i] = 1.0;
          s->rowidx[i] = r + 1;
        }
        didx = (didx + firstNonZeroRow_tmp) - 1;
      }
      offset = -1;
      for (int r{firstNonZeroRow_tmp}; r <= lastNonZeroRow_tmp; r++) {
        i = b->colidx[bc] + offset;
        if (b->rowidx[i] == r) {
          double val;
          val = static_cast<double>(av) + b->d[i];
          if (val != 0.0) {
            s->d[didx] = val;
            s->rowidx[didx] = r;
            didx++;
          }
          offset++;
        } else if (av != 0) {
          s->d[didx] = 1.0;
          s->rowidx[didx] = r;
          didx++;
        }
      }
      if (av != 0) {
        i = lastNonZeroRow_tmp + 1;
        av = s->m;
        for (int r{i}; r <= av; r++) {
          firstNonZeroRow_tmp = ((didx + r) - lastNonZeroRow_tmp) - 1;
          s->rowidx[firstNonZeroRow_tmp] = r;
          s->d[firstNonZeroRow_tmp] = 1.0;
        }
        didx = (didx + av) - lastNonZeroRow_tmp;
      }
      s->colidx[c + 1] = didx + 1;
      bc += bcInc;
    }
  }
}

//
// Arguments    : const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::b_minus(const sparse *b, sparse *s) const
{
  int aidx;
  int b_n;
  int didx;
  boolean_T x[2];
  boolean_T exitg1;
  boolean_T moreAToDo;
  didx = n;
  b_n = b->n;
  if (didx >= b_n) {
    b_n = didx;
  }
  didx = m;
  aidx = b->m;
  if (didx >= aidx) {
    aidx = didx;
  }
  sparse::allocEqsizeBinop(this, b, b_n, aidx, s);
  x[0] = (m == b->m);
  x[1] = (n == b->n);
  moreAToDo = true;
  didx = 0;
  exitg1 = false;
  while ((!exitg1) && (didx < 2)) {
    if (!x[didx]) {
      moreAToDo = false;
      exitg1 = true;
    } else {
      didx++;
    }
  }
  if (moreAToDo) {
    didx = 0;
    s->colidx[0] = 1;
    b_n = s->n;
    for (int c{0}; c < b_n; c++) {
      int bidx;
      int bidx_tmp;
      int moreAToDo_tmp;
      boolean_T moreBToDo;
      aidx = colidx[c];
      bidx_tmp = b->colidx[c];
      bidx = bidx_tmp - 1;
      moreAToDo_tmp = colidx[c + 1];
      moreAToDo = (colidx[c] < moreAToDo_tmp);
      moreBToDo = (bidx_tmp < b->colidx[c + 1]);
      while (moreAToDo || moreBToDo) {
        while ((aidx < moreAToDo_tmp) &&
               ((!moreBToDo) || (rowidx[aidx - 1] < b->rowidx[bidx]))) {
          s->d[didx] = 1.0;
          s->rowidx[didx] = rowidx[aidx - 1];
          didx++;
          aidx++;
        }
        moreAToDo = (aidx < moreAToDo_tmp);
        while ((bidx + 1 < b->colidx[c + 1]) &&
               ((!moreAToDo) || (b->rowidx[bidx] < rowidx[aidx - 1]))) {
          if (0.0 - b->d[bidx] != 0.0) {
            s->d[didx] = 0.0 - b->d[bidx];
            s->rowidx[didx] = b->rowidx[bidx];
            didx++;
          }
          bidx++;
        }
        while ((aidx < moreAToDo_tmp) && (bidx + 1 < b->colidx[c + 1]) &&
               (rowidx[aidx - 1] == b->rowidx[bidx])) {
          if (1.0 - b->d[bidx] != 0.0) {
            s->d[didx] = 1.0 - b->d[bidx];
            s->rowidx[didx] = b->rowidx[bidx];
            didx++;
          }
          bidx++;
          aidx++;
        }
        moreAToDo = (aidx < moreAToDo_tmp);
        moreBToDo = (bidx + 1 < b->colidx[c + 1]);
      }
      s->colidx[c + 1] = didx + 1;
    }
  } else if (n == 1) {
    if (b->m == 1) {
      sparse::e_sparseSparseRowExpandBinOp(b, this, s);
    } else {
      didx = 0;
      s->colidx[0] = 1;
      b_n = s->n;
      for (int c{0}; c < b_n; c++) {
        int bidx;
        int bidx_tmp;
        boolean_T moreBToDo;
        aidx = colidx[0];
        bidx_tmp = b->colidx[c];
        bidx = bidx_tmp - 1;
        moreAToDo = (colidx[0] < colidx[1]);
        moreBToDo = (bidx_tmp < b->colidx[c + 1]);
        while (moreAToDo || moreBToDo) {
          while ((aidx < colidx[1]) &&
                 ((!moreBToDo) || (rowidx[aidx - 1] < b->rowidx[bidx]))) {
            s->d[didx] = 1.0;
            s->rowidx[didx] = rowidx[aidx - 1];
            didx++;
            aidx++;
          }
          moreAToDo = (aidx < colidx[1]);
          while ((bidx + 1 < b->colidx[c + 1]) &&
                 ((!moreAToDo) || (b->rowidx[bidx] < rowidx[aidx - 1]))) {
            if (0.0 - b->d[bidx] != 0.0) {
              s->d[didx] = 0.0 - b->d[bidx];
              s->rowidx[didx] = b->rowidx[bidx];
              didx++;
            }
            bidx++;
          }
          while ((aidx < colidx[1]) && (bidx + 1 < b->colidx[c + 1]) &&
                 (rowidx[aidx - 1] == b->rowidx[bidx])) {
            if (1.0 - b->d[bidx] != 0.0) {
              s->d[didx] = 1.0 - b->d[bidx];
              s->rowidx[didx] = b->rowidx[bidx];
              didx++;
            }
            bidx++;
            aidx++;
          }
          moreAToDo = (aidx < colidx[1]);
          moreBToDo = (bidx + 1 < b->colidx[c + 1]);
        }
        s->colidx[c + 1] = didx + 1;
      }
    }
  } else if (b->n == 1) {
    if (m == 1) {
      sparse::b_sparseSparseRowExpandBinOp(this, b, s, true);
    } else {
      didx = 0;
      s->colidx[0] = 1;
      b_n = s->n;
      for (int c{0}; c < b_n; c++) {
        int bidx;
        int bidx_tmp;
        boolean_T moreBToDo;
        aidx = b->colidx[0] - 1;
        bidx_tmp = colidx[c];
        bidx = bidx_tmp - 1;
        moreAToDo = (b->colidx[0] < b->colidx[1]);
        moreBToDo = (bidx_tmp < colidx[c + 1]);
        while (moreAToDo || moreBToDo) {
          while ((aidx + 1 < b->colidx[1]) &&
                 ((!moreBToDo) || (b->rowidx[aidx] < rowidx[bidx]))) {
            if (0.0 - b->d[aidx] != 0.0) {
              s->d[didx] = 0.0 - b->d[aidx];
              s->rowidx[didx] = b->rowidx[aidx];
              didx++;
            }
            aidx++;
          }
          moreAToDo = (aidx + 1 < b->colidx[1]);
          while ((bidx + 1 < colidx[c + 1]) &&
                 ((!moreAToDo) || (rowidx[bidx] < b->rowidx[aidx]))) {
            s->d[didx] = 1.0;
            s->rowidx[didx] = rowidx[bidx];
            didx++;
            bidx++;
          }
          while ((aidx + 1 < b->colidx[1]) && (bidx + 1 < colidx[c + 1]) &&
                 (b->rowidx[aidx] == rowidx[bidx])) {
            if (1.0 - b->d[aidx] != 0.0) {
              s->d[didx] = 1.0 - b->d[aidx];
              s->rowidx[didx] = rowidx[bidx];
              didx++;
            }
            bidx++;
            aidx++;
          }
          moreAToDo = (aidx + 1 < b->colidx[1]);
          moreBToDo = (bidx + 1 < colidx[c + 1]);
        }
        s->colidx[c + 1] = didx + 1;
      }
    }
  } else if (m == 1) {
    sparse::b_sparseSparseRowExpandBinOp(this, b, s, false);
  } else if (b->m == 1) {
    sparse::f_sparseSparseRowExpandBinOp(b, this, s);
  }
}

//
// Arguments    : sparse *b_this
//                int numAllocRequested
//                int ub1
//                int lb2
//                int ub2
//                int offs
// Return Type  : void
//
void sparse::b_realloc(sparse *b_this, int numAllocRequested, int ub1, int lb2,
                       int ub2, int offs)
{
  array<double, 1U> dt;
  array<int, 1U> rowidxt;
  int highOrderA;
  int highOrderB;
  int lowOrderB;
  int overflow;
  int partialResults_idx_0_tmp;
  int partialResults_idx_1;
  int tmp;
  rowidxt.set_size(b_this->rowidx.size(0));
  partialResults_idx_1 = b_this->rowidx.size(0);
  for (highOrderA = 0; highOrderA < partialResults_idx_1; highOrderA++) {
    rowidxt[highOrderA] = b_this->rowidx[highOrderA];
  }
  dt.set_size(b_this->d.size(0));
  partialResults_idx_1 = b_this->d.size(0);
  for (highOrderA = 0; highOrderA < partialResults_idx_1; highOrderA++) {
    dt[highOrderA] = b_this->d[highOrderA];
  }
  highOrderA = b_this->m >> 16;
  partialResults_idx_1 = b_this->m & 65535;
  highOrderB = b_this->n >> 16;
  lowOrderB = b_this->n & 65535;
  partialResults_idx_0_tmp = partialResults_idx_1 * lowOrderB;
  tmp = partialResults_idx_1 * highOrderB;
  partialResults_idx_1 = tmp << 16;
  overflow = tmp >> 16;
  if (overflow <= 0) {
    tmp = highOrderA * lowOrderB;
    overflow += tmp >> 16;
    if (overflow <= 0) {
      overflow += highOrderA * highOrderB;
      if (overflow <= 0) {
        if (partialResults_idx_0_tmp > MAX_int32_T - partialResults_idx_1) {
          partialResults_idx_1 =
              (partialResults_idx_0_tmp + partialResults_idx_1) - MAX_int32_T;
          overflow++;
        } else {
          partialResults_idx_1 += partialResults_idx_0_tmp;
        }
        if (partialResults_idx_1 > MAX_int32_T - (tmp << 16)) {
          overflow++;
        }
      }
    }
  }
  if (overflow == 0) {
    partialResults_idx_1 = b_this->m * b_this->n;
    if (numAllocRequested <= partialResults_idx_1) {
      partialResults_idx_1 = numAllocRequested;
    }
    if (partialResults_idx_1 <= 1) {
      partialResults_idx_1 = 1;
    }
  } else if (numAllocRequested <= 1) {
    partialResults_idx_1 = 1;
  } else {
    partialResults_idx_1 = numAllocRequested;
  }
  b_this->rowidx.set_size(partialResults_idx_1);
  b_this->d.set_size(partialResults_idx_1);
  for (highOrderA = 0; highOrderA < partialResults_idx_1; highOrderA++) {
    b_this->rowidx[highOrderA] = 0;
    b_this->d[highOrderA] = 0.0;
  }
  b_this->maxnz = partialResults_idx_1;
  for (partialResults_idx_1 = 0; partialResults_idx_1 < ub1;
       partialResults_idx_1++) {
    b_this->rowidx[partialResults_idx_1] = rowidxt[partialResults_idx_1];
    b_this->d[partialResults_idx_1] = dt[partialResults_idx_1];
  }
  for (partialResults_idx_1 = lb2; partialResults_idx_1 <= ub2;
       partialResults_idx_1++) {
    highOrderA = (partialResults_idx_1 + offs) - 1;
    b_this->rowidx[highOrderA] = rowidxt[partialResults_idx_1 - 1];
    b_this->d[highOrderA] = dt[partialResults_idx_1 - 1];
  }
}

//
// Arguments    : sparse *y
// Return Type  : void
//
void sparse::ctranspose(sparse *y) const
{
  array<int, 1U> counts;
  int nl;
  int numalloc;
  int outridx;
  int outridx_tmp;
  nl = n;
  y->m = n;
  y->n = m;
  numalloc = colidx[colidx.size(0) - 1] - 1;
  if (numalloc < 1) {
    numalloc = 1;
  }
  y->d.set_size(numalloc);
  y->maxnz = numalloc;
  outridx = m + 1;
  y->colidx.set_size(outridx);
  y->colidx[0] = 1;
  y->rowidx.set_size(numalloc);
  for (outridx_tmp = 0; outridx_tmp < numalloc; outridx_tmp++) {
    y->d[outridx_tmp] = 0.0;
    y->rowidx[outridx_tmp] = 0;
  }
  outridx_tmp = m;
  for (int c{0}; c < outridx_tmp; c++) {
    y->colidx[c + 1] = 1;
  }
  y->fillIn();
  if ((m != 0) && (n != 0)) {
    numalloc = y->colidx.size(0);
    for (outridx_tmp = 0; outridx_tmp < numalloc; outridx_tmp++) {
      y->colidx[outridx_tmp] = 0;
    }
    outridx_tmp = colidx[colidx.size(0) - 1];
    for (numalloc = 0; numalloc <= outridx_tmp - 2; numalloc++) {
      y->colidx[rowidx[numalloc]] = y->colidx[rowidx[numalloc]] + 1;
    }
    y->colidx[0] = 1;
    for (numalloc = 2; numalloc <= outridx; numalloc++) {
      y->colidx[numalloc - 1] =
          y->colidx[numalloc - 1] + y->colidx[numalloc - 2];
    }
    counts.set_size(m);
    numalloc = m;
    for (outridx = 0; outridx < numalloc; outridx++) {
      counts[outridx] = 0;
    }
    for (int c{0}; c < nl; c++) {
      for (numalloc = colidx[c] - 1; numalloc + 1 < colidx[c + 1]; numalloc++) {
        outridx_tmp = counts[rowidx[numalloc] - 1];
        outridx = (outridx_tmp + y->colidx[rowidx[numalloc] - 1]) - 1;
        y->d[outridx] = d[numalloc];
        y->rowidx[outridx] = c + 1;
        counts[rowidx[numalloc] - 1] = outridx_tmp + 1;
      }
    }
  }
}

//
// Arguments    : void
// Return Type  : void
//
void sparse::fillIn()
{
  int i;
  int idx;
  idx = 1;
  i = colidx.size(0);
  for (int c{0}; c <= i - 2; c++) {
    int ridx;
    ridx = colidx[c];
    colidx[c] = idx;
    int exitg1;
    int i1;
    do {
      exitg1 = 0;
      i1 = colidx[c + 1];
      if (ridx < i1) {
        double val;
        int currRowIdx;
        val = 0.0;
        currRowIdx = rowidx[ridx - 1];
        while ((ridx < i1) && (rowidx[ridx - 1] == currRowIdx)) {
          val += d[ridx - 1];
          ridx++;
        }
        if (val != 0.0) {
          d[idx - 1] = val;
          rowidx[idx - 1] = currRowIdx;
          idx++;
        }
      } else {
        exitg1 = 1;
      }
    } while (exitg1 == 0);
  }
  colidx[colidx.size(0) - 1] = idx;
}

//
// Arguments    : sparse *y
// Return Type  : void
//
void sparse::inv(sparse *y) const
{
  b_sparse s;
  sparse b;
  sparse in;
  array<double, 2U> tmp;
  int loop_ub;
  int unnamed_idx_0;
  speye(static_cast<double>(m), &b);
  if ((m == 0) || (n == 0) || (b.m == 0) || (b.n == 0)) {
    int i;
    y->m = n;
    y->n = b.n;
    y->d.set_size(1);
    y->d[0] = 0.0;
    y->maxnz = 1;
    y->colidx.set_size(b.n + 1);
    y->colidx[0] = 1;
    y->rowidx.set_size(1);
    y->rowidx[0] = 0;
    i = b.n;
    for (int numalloc{0}; numalloc < i; numalloc++) {
      y->colidx[numalloc + 1] = 1;
    }
    y->fillIn();
  } else if (b.m == n) {
    cs_di *cxA;
    cs_din *N;
    cs_dis *S;
    if (m < n) {
      ctranspose(&in);
      cxA = makeCXSparseMatrix(in.colidx[in.colidx.size(0) - 1] - 1, in.n, in.m,
                               &(in.colidx.data())[0], &(in.rowidx.data())[0],
                               &(in.d.data())[0]);
    } else {
      cxA =
          makeCXSparseMatrix(colidx[colidx.size(0) - 1] - 1, n, m,
                             &(((::coder::array<int, 1U> *)&colidx)->data())[0],
                             &(((::coder::array<int, 1U> *)&rowidx)->data())[0],
                             &(((::coder::array<double, 1U> *)&d)->data())[0]);
    }
    S = cs_di_sqr(2, cxA, 0);
    N = cs_di_lu(cxA, S, 1);
    cs_di_spfree(cxA);
    if (N == nullptr) {
      cs_di_sfree(S);
      cs_di_nfree(N);
      internal::CXSparseAPI::iteratedQR(this, &b, n, y);
    } else {
      int i;
      int numalloc;
      y->m = n;
      y->n = b.n;
      y->d.set_size(1);
      y->d[0] = 0.0;
      y->maxnz = 1;
      y->colidx.set_size(b.n + 1);
      y->colidx[0] = 1;
      y->rowidx.set_size(1);
      y->rowidx[0] = 0;
      i = b.n;
      for (numalloc = 0; numalloc < i; numalloc++) {
        y->colidx[numalloc + 1] = 1;
      }
      y->fillIn();
      i = b.n;
      if (b.n - 1 >= 0) {
        s.colidx.set_size(2);
        unnamed_idx_0 = b.m;
        loop_ub = b.m;
      }
      for (int b_i{0}; b_i < i; b_i++) {
        int b_n;
        int nzColAlloc;
        int nzRhs;
        int sm_tmp;
        nzColAlloc = b.colidx[b_i];
        nzRhs = b.colidx[b_i + 1] - nzColAlloc;
        if (nzRhs >= 1) {
          numalloc = nzRhs;
        } else {
          numalloc = 1;
        }
        s.d.set_size(numalloc);
        for (b_n = 0; b_n < numalloc; b_n++) {
          s.d[b_n] = 0.0;
        }
        s.rowidx.set_size(numalloc);
        for (b_n = 0; b_n < numalloc; b_n++) {
          s.rowidx[b_n] = 0;
        }
        s.colidx[0] = 1;
        s.colidx[1] = 1;
        if (nzRhs != 0) {
          for (int k{0}; k < nzRhs; k++) {
            s.d[k] = 1.0;
            s.rowidx[k] = b.rowidx[(nzColAlloc + k) - 1];
          }
          s.colidx[1] = nzRhs + 1;
        }
        tmp.set_size(unnamed_idx_0, 1);
        for (b_n = 0; b_n < loop_ub; b_n++) {
          tmp[b_n] = 0.0;
        }
        numalloc = s.colidx[1] - 1;
        b_n = s.colidx[0];
        for (nzColAlloc = b_n; nzColAlloc <= numalloc; nzColAlloc++) {
          tmp[s.rowidx[nzColAlloc - 1] - 1] = s.d[nzColAlloc - 1];
        }
        solve_from_lu_di(N, S, (double *)&tmp[0], b.m);
        sm_tmp = y->m;
        b_n = y->colidx[y->colidx.size(0) - 1];
        numalloc = y->colidx[b_i];
        nzColAlloc = y->colidx[b_i + 1] - numalloc;
        nzRhs = 0;
        for (int k{0}; k < sm_tmp; k++) {
          if (!(tmp[k] == 0.0)) {
            nzRhs++;
          }
        }
        if (nzColAlloc < nzRhs) {
          nzRhs -= nzColAlloc;
          numalloc = (y->maxnz - y->colidx[y->colidx.size(0) - 1]) + 1;
          if (numalloc < nzRhs) {
            sparse::b_realloc(y, (y->maxnz + nzRhs) - numalloc,
                              y->colidx[b_i] - 1, y->colidx[b_i + 1],
                              y->colidx[y->colidx.size(0) - 1] - 1, nzRhs);
          } else {
            numalloc = (y->colidx[b_i + 1] + nzRhs) - 1;
            nzColAlloc = y->colidx[y->colidx.size(0) - 1] - y->colidx[b_i + 1];
            if (nzColAlloc > 0) {
              std::memmove((void *)&y->rowidx[numalloc],
                           (void *)&y->rowidx[y->colidx[b_i + 1] - 1],
                           (unsigned int)((size_t)nzColAlloc * sizeof(int)));
              std::memmove((void *)&y->d[numalloc],
                           (void *)&y->d[y->colidx[b_i + 1] - 1],
                           (unsigned int)((size_t)nzColAlloc * sizeof(double)));
            }
          }
          numalloc = y->colidx[b_i] - 1;
          for (int k{0}; k < sm_tmp; k++) {
            double rhsv;
            rhsv = tmp[k];
            if (rhsv != 0.0) {
              y->rowidx[numalloc] = k + 1;
              y->d[numalloc] = rhsv;
              numalloc++;
            }
          }
          b_n = b_i + 2;
          numalloc = y->n + 1;
          for (int k{b_n}; k <= numalloc; k++) {
            y->colidx[k - 1] = y->colidx[k - 1] + nzRhs;
          }
        } else {
          numalloc--;
          for (int k{0}; k < sm_tmp; k++) {
            double rhsv;
            rhsv = tmp[k];
            if (rhsv != 0.0) {
              y->rowidx[numalloc] = k + 1;
              y->d[numalloc] = rhsv;
              numalloc++;
            }
          }
          nzRhs = nzColAlloc - nzRhs;
          if (nzRhs > 0) {
            nzColAlloc = b_n - y->colidx[b_i + 1];
            if (nzColAlloc > 0) {
              std::memmove((void *)&y->rowidx[numalloc],
                           (void *)&y->rowidx[y->colidx[b_i + 1] - 1],
                           (unsigned int)((size_t)nzColAlloc * sizeof(int)));
              std::memmove((void *)&y->d[numalloc],
                           (void *)&y->d[y->colidx[b_i + 1] - 1],
                           (unsigned int)((size_t)nzColAlloc * sizeof(double)));
            }
            b_n = b_i + 2;
            numalloc = y->n + 1;
            for (int k{b_n}; k <= numalloc; k++) {
              y->colidx[k - 1] = y->colidx[k - 1] - nzRhs;
            }
          }
        }
      }
      cs_di_sfree(S);
      cs_di_nfree(N);
    }
  } else {
    internal::CXSparseAPI::iteratedQR(this, &b, n, y);
  }
}

//
// Arguments    : const sparse *b
//                sparse *c
// Return Type  : void
//
void sparse::mtimes(const sparse *b, sparse *c) const
{
  array<double, 1U> wd;
  array<int, 1U> flag;
  int bcidx;
  int blen;
  int cmax;
  int cnnz;
  int cstart;
  int i;
  int i1;
  int j;
  int pb;
  c->colidx.set_size(b->colidx.size(0));
  blen = b->colidx.size(0);
  for (i = 0; i < blen; i++) {
    c->colidx[i] = 0;
  }
  flag.set_size(m);
  blen = m;
  for (i = 0; i < blen; i++) {
    flag[i] = 0;
  }
  cnnz = 0;
  j = 0;
  int exitg1;
  do {
    exitg1 = 0;
    if (j <= b->n - 1) {
      bcidx = b->colidx[j];
      cstart = cnnz;
      cmax = cnnz + m;
      c->colidx[j] = cnnz + 1;
      while ((bcidx < b->colidx[j + 1]) && (cnnz <= cmax)) {
        blen = b->rowidx[bcidx - 1];
        pb = colidx[blen] - 1;
        i = colidx[blen - 1];
        for (blen = i; blen <= pb; blen++) {
          i1 = rowidx[blen - 1] - 1;
          if (flag[i1] != j + 1) {
            flag[i1] = j + 1;
            cnnz++;
          }
        }
        bcidx++;
      }
      if (cnnz < cstart) {
        exitg1 = 1;
      } else {
        j++;
      }
    } else {
      c->colidx[b->n] = cnnz + 1;
      exitg1 = 1;
    }
  } while (exitg1 == 0);
  c->m = m;
  c->n = b->n;
  if (cnnz < 1) {
    cnnz = 1;
  }
  c->maxnz = cnnz;
  c->d.set_size(cnnz);
  c->rowidx.set_size(cnnz);
  wd.set_size(m);
  flag.set_size(m);
  blen = m;
  for (i = 0; i < blen; i++) {
    flag[i] = 0;
  }
  pb = 0;
  cnnz = -1;
  i = b->n;
  for (j = 0; j < i; j++) {
    int pcstart;
    boolean_T needSort;
    needSort = false;
    pcstart = cnnz + 2;
    blen = (b->colidx[j + 1] - pb) - 1;
    if (blen != 0) {
      if (blen == 1) {
        cmax = colidx[b->rowidx[pb]] - 1;
        i1 = colidx[b->rowidx[pb] - 1];
        for (int pa{i1}; pa <= cmax; pa++) {
          blen = rowidx[pa - 1];
          c->rowidx[((cnnz + pa) - i1) + 1] = blen;
          wd[blen - 1] = d[pa - 1] * b->d[pb];
        }
        cnnz = (cnnz + colidx[b->rowidx[pb]]) - colidx[b->rowidx[pb] - 1];
        pb++;
      } else {
        blen = colidx[b->rowidx[pb]];
        cmax = blen - 1;
        i1 = colidx[b->rowidx[pb] - 1];
        for (int pa{i1}; pa <= cmax; pa++) {
          bcidx = rowidx[pa - 1];
          cstart = (cnnz + pa) - i1;
          flag[bcidx - 1] = cstart + 2;
          c->rowidx[cstart + 1] = bcidx;
          wd[bcidx - 1] = d[pa - 1] * b->d[pb];
        }
        cnnz = (cnnz + blen) - i1;
        for (pb++; pb + 1 < b->colidx[j + 1]; pb++) {
          double bd;
          bd = b->d[pb];
          cmax = colidx[b->rowidx[pb]] - 1;
          i1 = colidx[b->rowidx[pb] - 1];
          for (int pa{i1}; pa <= cmax; pa++) {
            blen = rowidx[pa - 1];
            if (flag[blen - 1] < pcstart) {
              cnnz++;
              flag[blen - 1] = cnnz + 1;
              c->rowidx[cnnz] = blen;
              wd[blen - 1] = d[pa - 1] * bd;
              needSort = true;
            } else {
              wd[blen - 1] = wd[blen - 1] + d[pa - 1] * bd;
            }
          }
        }
      }
    }
    blen = c->colidx[j + 1] - 1;
    pcstart = c->colidx[j];
    if (needSort) {
      internal::introsort(c->rowidx, c->colidx[j], c->colidx[j + 1] - 1);
    }
    for (bcidx = pcstart; bcidx <= blen; bcidx++) {
      c->d[bcidx - 1] = wd[c->rowidx[bcidx - 1] - 1];
    }
  }
  c->b_fillIn();
}

//
// Arguments    : const sparse *b
//                sparse *s
// Return Type  : void
//
void sparse::plus(const sparse *b, sparse *s) const
{
  int aidx;
  int b_n;
  int didx;
  boolean_T x[2];
  boolean_T exitg1;
  boolean_T moreAToDo;
  didx = n;
  b_n = b->n;
  if (didx >= b_n) {
    b_n = didx;
  }
  didx = m;
  aidx = b->m;
  if (didx >= aidx) {
    aidx = didx;
  }
  sparse::allocEqsizeBinop(this, b, b_n, aidx, s);
  x[0] = (m == b->m);
  x[1] = (n == b->n);
  moreAToDo = true;
  didx = 0;
  exitg1 = false;
  while ((!exitg1) && (didx < 2)) {
    if (!x[didx]) {
      moreAToDo = false;
      exitg1 = true;
    } else {
      didx++;
    }
  }
  if (moreAToDo) {
    didx = 0;
    s->colidx[0] = 1;
    b_n = s->n;
    for (int c{0}; c < b_n; c++) {
      int bidx;
      int bidx_tmp;
      int moreAToDo_tmp;
      boolean_T moreBToDo;
      aidx = colidx[c];
      bidx_tmp = b->colidx[c];
      bidx = bidx_tmp - 1;
      moreAToDo_tmp = colidx[c + 1];
      moreAToDo = (colidx[c] < moreAToDo_tmp);
      moreBToDo = (bidx_tmp < b->colidx[c + 1]);
      while (moreAToDo || moreBToDo) {
        while ((aidx < moreAToDo_tmp) &&
               ((!moreBToDo) || (rowidx[aidx - 1] < b->rowidx[bidx]))) {
          s->d[didx] = 1.0;
          s->rowidx[didx] = rowidx[aidx - 1];
          didx++;
          aidx++;
        }
        moreAToDo = (aidx < moreAToDo_tmp);
        while ((bidx + 1 < b->colidx[c + 1]) &&
               ((!moreAToDo) || (b->rowidx[bidx] < rowidx[aidx - 1]))) {
          if (b->d[bidx] != 0.0) {
            s->d[didx] = b->d[bidx];
            s->rowidx[didx] = b->rowidx[bidx];
            didx++;
          }
          bidx++;
        }
        while ((aidx < moreAToDo_tmp) && (bidx + 1 < b->colidx[c + 1]) &&
               (rowidx[aidx - 1] == b->rowidx[bidx])) {
          if (b->d[bidx] + 1.0 != 0.0) {
            s->d[didx] = b->d[bidx] + 1.0;
            s->rowidx[didx] = b->rowidx[bidx];
            didx++;
          }
          bidx++;
          aidx++;
        }
        moreAToDo = (aidx < moreAToDo_tmp);
        moreBToDo = (bidx + 1 < b->colidx[c + 1]);
      }
      s->colidx[c + 1] = didx + 1;
    }
  } else if (n == 1) {
    if (b->m == 1) {
      sparse::c_sparseSparseRowExpandBinOp(b, this, s);
    } else {
      didx = 0;
      s->colidx[0] = 1;
      b_n = s->n;
      for (int c{0}; c < b_n; c++) {
        int bidx;
        int bidx_tmp;
        boolean_T moreBToDo;
        aidx = colidx[0];
        bidx_tmp = b->colidx[c];
        bidx = bidx_tmp - 1;
        moreAToDo = (colidx[0] < colidx[1]);
        moreBToDo = (bidx_tmp < b->colidx[c + 1]);
        while (moreAToDo || moreBToDo) {
          while ((aidx < colidx[1]) &&
                 ((!moreBToDo) || (rowidx[aidx - 1] < b->rowidx[bidx]))) {
            s->d[didx] = 1.0;
            s->rowidx[didx] = rowidx[aidx - 1];
            didx++;
            aidx++;
          }
          moreAToDo = (aidx < colidx[1]);
          while ((bidx + 1 < b->colidx[c + 1]) &&
                 ((!moreAToDo) || (b->rowidx[bidx] < rowidx[aidx - 1]))) {
            if (b->d[bidx] != 0.0) {
              s->d[didx] = b->d[bidx];
              s->rowidx[didx] = b->rowidx[bidx];
              didx++;
            }
            bidx++;
          }
          while ((aidx < colidx[1]) && (bidx + 1 < b->colidx[c + 1]) &&
                 (rowidx[aidx - 1] == b->rowidx[bidx])) {
            if (b->d[bidx] + 1.0 != 0.0) {
              s->d[didx] = b->d[bidx] + 1.0;
              s->rowidx[didx] = b->rowidx[bidx];
              didx++;
            }
            bidx++;
            aidx++;
          }
          moreAToDo = (aidx < colidx[1]);
          moreBToDo = (bidx + 1 < b->colidx[c + 1]);
        }
        s->colidx[c + 1] = didx + 1;
      }
    }
  } else if (b->n == 1) {
    if (m == 1) {
      sparse::sparseSparseRowExpandBinOp(this, b, s, true);
    } else {
      didx = 0;
      s->colidx[0] = 1;
      b_n = s->n;
      for (int c{0}; c < b_n; c++) {
        int bidx;
        int bidx_tmp;
        boolean_T moreBToDo;
        aidx = b->colidx[0] - 1;
        bidx_tmp = colidx[c];
        bidx = bidx_tmp - 1;
        moreAToDo = (b->colidx[0] < b->colidx[1]);
        moreBToDo = (bidx_tmp < colidx[c + 1]);
        while (moreAToDo || moreBToDo) {
          while ((aidx + 1 < b->colidx[1]) &&
                 ((!moreBToDo) || (b->rowidx[aidx] < rowidx[bidx]))) {
            if (b->d[aidx] != 0.0) {
              s->d[didx] = b->d[aidx];
              s->rowidx[didx] = b->rowidx[aidx];
              didx++;
            }
            aidx++;
          }
          moreAToDo = (aidx + 1 < b->colidx[1]);
          while ((bidx + 1 < colidx[c + 1]) &&
                 ((!moreAToDo) || (rowidx[bidx] < b->rowidx[aidx]))) {
            s->d[didx] = 1.0;
            s->rowidx[didx] = rowidx[bidx];
            didx++;
            bidx++;
          }
          while ((aidx + 1 < b->colidx[1]) && (bidx + 1 < colidx[c + 1]) &&
                 (b->rowidx[aidx] == rowidx[bidx])) {
            if (b->d[aidx] + 1.0 != 0.0) {
              s->d[didx] = b->d[aidx] + 1.0;
              s->rowidx[didx] = rowidx[bidx];
              didx++;
            }
            bidx++;
            aidx++;
          }
          moreAToDo = (aidx + 1 < b->colidx[1]);
          moreBToDo = (bidx + 1 < colidx[c + 1]);
        }
        s->colidx[c + 1] = didx + 1;
      }
    }
  } else if (m == 1) {
    sparse::sparseSparseRowExpandBinOp(this, b, s, false);
  } else if (b->m == 1) {
    sparse::d_sparseSparseRowExpandBinOp(b, this, s);
  }
}

//
// Arguments    : double a
//                sparse *s
// Return Type  : void
//
void sparse::times(double a, sparse *s) const
{
  array<double, 2U> S;
  array<double, 1U> tmpd;
  if (a * 0.0 == 0.0) {
    int b_n;
    int i;
    int numalloc;
    int row;
    row = colidx[colidx.size(0) - 1];
    if (colidx[colidx.size(0) - 1] - 1 < 1) {
      b_n = 0;
    } else {
      b_n = colidx[colidx.size(0) - 1] - 1;
    }
    tmpd.set_size(b_n);
    for (i = 0; i < b_n; i++) {
      tmpd[i] = a * d[i];
    }
    s->m = m;
    s->n = n;
    numalloc = colidx[colidx.size(0) - 1] - 1;
    if (numalloc < 1) {
      numalloc = 1;
    }
    s->d.set_size(numalloc);
    s->maxnz = numalloc;
    s->colidx.set_size(n + 1);
    s->rowidx.set_size(numalloc);
    for (i = 0; i < numalloc; i++) {
      s->d[i] = 0.0;
      s->rowidx[i] = 0;
    }
    i = n;
    for (b_n = 0; b_n < i; b_n++) {
      s->colidx[b_n + 1] = 1;
    }
    i = s->colidx.size(0);
    for (b_n = 0; b_n <= i - 2; b_n++) {
      s->colidx[b_n] = 1;
    }
    if (colidx[colidx.size(0) - 1] - 1 < 1) {
      b_n = 1;
    } else {
      b_n = colidx[colidx.size(0) - 1];
    }
    for (i = 0; i <= b_n - 2; i++) {
      s->rowidx[i] = rowidx[i];
    }
    s->colidx.set_size(colidx.size(0));
    b_n = colidx.size(0);
    for (i = 0; i < b_n; i++) {
      s->colidx[i] = colidx[i];
    }
    for (b_n = 0; b_n <= row - 2; b_n++) {
      s->d[b_n] = tmpd[b_n];
    }
    s->b_fillIn();
  } else {
    int b_n;
    int i;
    int mInt;
    int nInt;
    int numalloc;
    int row;
    S.set_size(m, n);
    b_n = m * n;
    for (i = 0; i < b_n; i++) {
      S[i] = rtNaN;
    }
    b_n = n;
    for (int col{0}; col < b_n; col++) {
      i = colidx[col];
      row = colidx[col + 1] - 1;
      for (numalloc = i; numalloc <= row; numalloc++) {
        S[(rowidx[numalloc - 1] + S.size(0) * col) - 1] = a * d[numalloc - 1];
      }
    }
    mInt = S.size(0);
    nInt = S.size(1);
    numalloc = 0;
    i = S.size(0) * S.size(1);
    for (b_n = 0; b_n < i; b_n++) {
      if (S[b_n] != 0.0) {
        numalloc++;
      }
    }
    s->m = S.size(0);
    s->n = S.size(1);
    if (numalloc < 1) {
      numalloc = 1;
    }
    s->maxnz = numalloc;
    s->d.set_size(numalloc);
    for (i = 0; i < numalloc; i++) {
      s->d[i] = 0.0;
    }
    s->colidx.set_size(S.size(1) + 1);
    b_n = S.size(1);
    for (i = 0; i <= b_n; i++) {
      s->colidx[i] = 0;
    }
    s->colidx[0] = 1;
    s->rowidx.set_size(numalloc);
    for (i = 0; i < numalloc; i++) {
      s->rowidx[i] = 0;
    }
    s->rowidx[0] = 1;
    b_n = 0;
    for (int col{0}; col < nInt; col++) {
      for (row = 0; row < mInt; row++) {
        double xrc;
        xrc = S[row + S.size(0) * col];
        if (xrc != 0.0) {
          s->rowidx[b_n] = row + 1;
          s->d[b_n] = xrc;
          b_n++;
        }
      }
      s->colidx[col + 1] = b_n + 1;
    }
  }
}

} // namespace coder

//
// File trailer for sparse.cpp
//
// [EOF]
//
